<?php
namespace app\http\controller\api;

use app\http\controller\api\Base;
use cw\facade\Cache;

class Login extends Base
{
    public function register($request)
    {
        $input = $request->post();
        if (empty($input)) {
            return api_json_return(2);
        }
        $username = base64_decode($input['username']);
        $password = \base64_decode($input['password']);
        $rst = validate('app\common\validate\Login.register', ['username' => $username, 'password' => $password]);
        if ($rst !== true) {
            $msg = '用户注册失败：注册数据验证未通过。' . ' username => ' . $username . ', password => ' . $password . ', clientid => ' . $this->clientid . ', rst => ' . $rst;
            log_msg($msg, 'error', $this->log_filename_apperr);
            return api_json_return(1, $rst);
        }

        $user_info = $this->db->get('users', ['id', 'username'], ['username' => $username]);
        if (!empty($user_info)) {
            return api_json_return(10012);
        }
        $data = [
            'username' => $username,
            'password' => \password_hash($password, PASSWORD_DEFAULT),
            'picture' => 'http://' . $request->host() . '/upload/default/default_user_avatar.jpg',
            'token' => make_token(),
            'expire' => $this->t + API_TOKEN_EXPIRE,
            'status' => 1,
            'spaces' => USER_SPACES,
            'created_at' => $this->t,
            'updated_at' => $this->t,
        ];
        $spaces_data = [
            'uid' => 0,
            'spaces' => 0,
        ];
        $this->db->pdo->beginTransaction();
        $res_u = $this->db->insert('users', $data)->rowCount();
        // var_dump($this->db->id());return 1212121212;
        if ($res_u === 1) {
            $user_id = $this->db->id();
            $res_s = $this->db->insert('user_spaces', ['uid' => $user_id, 'spaces' => 0])->rowCount();
            if ($res_s === 1) {
                $this->db->pdo->commit();
                return api_json_return(0);
            } else {
                $msg = '用户注册失败：插入数据（用户使用空间记录表）失败。' . ' username => ' . $username . ', password => ' . $password . ', clientid => ' . $this->clientid . ', user_id => ' . $user_id;
                log_msg($msg, 'error', $this->log_filename_apperr);
                return api_json_return(1);
            }
        } else {
            $msg = '用户注册失败：插入数据（用户表）失败。' . ' username => ' . $username . ', password => ' . $password . ', clientid => ' . $this->clientid . ', user_id => ' . $user_id;
            log_msg($msg, 'error', $this->log_filename_apperr);
            return api_json_return(1);
        }
    }



    public function login($request)
    {
        $input = $request->post();
        if (empty($input)) {
            return api_json_return(2);
        }
        $username = \base64_decode($input['username']);
        $password = \base64_decode($input['password']);

        $password_err_num_key = 'password_error_numbers:' . $username;
        if (Cache::has($password_err_num_key) && Cache::get($password_err_num_key) >= 5) {
            $msg = '用户登录失败：输入错误密码次数达到或者大于 5 次，账号已经被锁定。' . ' username => ' . $input['username'] . ', password => ' . $input['password'] . ', clientid => ' . $this->clientid;
            log_msg($msg, 'error', $this->log_filename_apperr);
            echo $msg . PHP_EOL;
            return api_json_return(10005);
        }
        

        $user_info = $this->db->get('users', ['id', 'password', 'status', 'spaces', 'username', 'picture'], ['username' => $username]);
        if (empty($user_info)) {
            return api_json_return(10003);
        }
        if ($user_info['status'] != 1) {
            return api_json_return(10004);
        }
        if (!\password_verify($password, $user_info['password'])) {
            if (Cache::has($password_err_num_key)) {
                if (Cache::get($password_err_num_key) < 5) {
                    Cache::inc($password_err_num_key);
                }
            } else {
                Cache::set($password_err_num_key, 1, 300);
            }
            $msg = '用户登录失败：输入错误密码。' . ' username => ' . $username . ', password => ' . $password . ', uid => ' . $user_info['id'] . ', clientid => ' . $this->clientid;
            log_msg($msg, 'error', $this->log_filename_apperr);
            echo $msg . PHP_EOL;
            return api_json_return(10003);
        }
        
        $token = \make_token();
        $up_data = [
            'token' => $token,
            'expire' => $this->t + \API_TOKEN_EXPIRE,
            'updated_at' => $this->t,
        ];
        $res = $this->db->update('users', $up_data, ['id' => $user_info['id']])->rowCount();
        if ($res === 1) {
            global $clientid;
            $clientid = $up_data['token'];
            cache('user_spaces', $user_info['spaces']);
            cache($token, $user_info['id']);
            return api_json_return(0, '', ['token' => $token, 'expire' => $up_data['expire'], 'username' => $user_info['username'], 'avatar' => $user_info['picture']]);
        } else {
            $msg = '用户登录失败：更新数据失败。res => ' . $res . ', username => ' . $username . ', password => ' . $password . ', uid => ' . $user_info['id'] . ', clientid => ' . $this->clientid;
            log_msg($msg, 'error', $this->log_filename_apperr);
            return api_json_return(1);
        }
    }


    public function resetPassword($request)
    {
        $input = $request->post();
        $token = $request->header('token');
        if (
            empty($input) ||
            empty($input['username']) ||
            empty($input['old_password']) ||
            empty($input['new_password'])
        ) {
            return api_json_return(2);
        }

        $user_info = $this->db->get('users', ['id', 'password', 'status'], ['username' => $input['username'], 'token' => $token]);
        if (empty($user_info)) {
            return api_json_return(10003);
        }
        if ($user_info['status'] != 1) {
            return api_json_return(10004);
        }
        if (!password_verify($input['old_password'], $user_info['password'])) {
            return api_json_return(10003);
        }

        $up_data = [
            'password' => password_hash($input['new_password'], PASSWORD_DEFAULT),
            'updated_at' => $this->t,
        ];
        $res = $this->db->update('users', $up_data, ['id' => $user_info['id']])->rowCount();
        if ($res === 1) {
            return api_json_return(0);
        } else {
            $msg = '重置密码失败：更新数据失败。res => ' . $res . ', username => ' . $input['username'] . ', old_password => ' . $input['old_password'] . ', new_password => ' . $input['new_password'] . ', user_info => ' . json_encode($user_info);
            log_msg($msg, 'error', $this->log_filename_apperr);
            return api_json_return(1);
        }
    }



    public function logout($request)
    {
        $token = $request->header('token');
        $res = $this->db
            ->update('users', ['token' => '', 'expire' => 1], ['token' => $token])
            ->rowCount();
        if ($res === 1) {
            return api_json_return(0);
        } else {
            return api_json_return(1);
        }
    }
}
